package com.ling.plasticene.vary;

import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.util.SparseArray;
import android.view.View;

import com.ling.plasticene.common.Stateable;

/**
 * 不同状态切换View帮助类
 * <p/>
 * Created by lingquan(quan.ling@hotmail.com) on 15/12/8.
 */
public class VaryHelper implements Stateable {
    /**
     * 替换模式
     */
    public static final int MODE_REPLACE = 0;

    /**
     * 覆盖模式
     */
    public static final int MODE_COVER = 1;

    VaryImp mVaryImp;
    int mState = NORMAL;
    SparseArray<View> mStateViews = new SparseArray<>();

    public VaryHelper(View view) {
        this(view, MODE_REPLACE);
    }

    public VaryHelper(View view, int mode) {
        if (mode == MODE_COVER) {
            mVaryImp = new VaryCoverImp(view);
        } else if (mode == MODE_REPLACE) {
            mVaryImp = new VaryReplaceImp(view);
        } else {
            throw new IllegalArgumentException("模式设置错误!");
        }

        setViewForState(view, NORMAL);
    }

    @Nullable
    public View getStateView(int state) {
        return mStateViews.get(state);
    }

    public void showDataView() {
        setState(NORMAL);
    }

    public void showLoadingView() {
        setState(LOADING);
    }

    public void showEmptyView() {
        setState(EMPTY);
    }

    public void showErrorView() {
        setState(ERROR);
    }

    @Override
    public void setState(int state) {
        if (mState == state) return;

        View v = getStateView(state);
        if (v == null) {
            throw new IllegalArgumentException("Not set view for this state");
        }

        mVaryImp.showLayout(v);
        mState = state;
    }

    /**
     * Sets the view for the given view state
     *
     * @param view          The {@link View} to use
     * @param state         The to set
     * @param switchToState If the  should be switched to
     */
    public void setViewForState(View view, int state, boolean switchToState) {
        View old = mStateViews.get(state);      //当前显示的View正好是修改状态view,则强制切换View
        if (!switchToState && old != null && mVaryImp.getCurrentLayout() == old) {
            switchToState = true;
        }

        view.setClickable(true);
        mStateViews.put(state, view);

        if (switchToState) setState(state);
    }

    /**
     * Sets the {@link View} for the given
     *
     * @param view  The {@link View} to use
     * @param state
     */
    public void setViewForState(View view, int state) {
        setViewForState(view, state, false);
    }

    /**
     * Sets the {@link View} for the given
     *
     * @param layoutRes     Layout resource id
     * @param state         The  to set
     * @param switchToState If the  should be switched to
     */
    public void setViewForState(@LayoutRes int layoutRes, int state, boolean switchToState) {
        setViewForState(mVaryImp.inflate(layoutRes), state, switchToState);
    }

    /**
     * Sets the {@link View} for the given
     *
     * @param layoutRes Layout resource id
     * @param state     The {@link View} state to set
     */
    public void setViewForState(@LayoutRes int layoutRes, int state) {
        setViewForState(layoutRes, state, false);
    }

    public View inflate(int resId) {
        return mVaryImp.inflate(resId);
    }

}
